package com.write.program.socket;

import com.write.program.socket.message.LogoutMessage;

import java.io.IOException;
import java.net.ServerSocket;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Endstart
 * Date: 2019-11-20
 * Time: 23:21
 */
public class ServerManager extends Thread {
    public Set<ServerSocketService> socketManagerSet = new HashSet<>();

    private int serverPort;
    private int timeoutSecond;
    private boolean running;
    private ServerSocket serverSocket;

    /**
     * @param serverPort    服务端口
     * @param timeoutSecond 超时时间/秒
     * @throws IOException
     */
    public ServerManager(int serverPort, int timeoutSecond) throws IOException {
        this.serverPort = serverPort;
        this.timeoutSecond = timeoutSecond;
        this.serverSocket = new ServerSocket(serverPort);
    }

    @Override
    public void run() {
        running = true;
        try {
            while (running) {
                // 接收其他peer的TCP请求
//                System.out.println("wait client connect...");
                ServerSocketService serverSocketService = new ServerSocketService(this.serverSocket.accept(),this);
//                System.out.println("receive PrintLinkList client connect:" + serverSocketService.getSocket().getInetAddress().getHostAddress());

                addServerSocket(serverSocketService);
                serverSocketService.start();

                // 如果设了超时断开，需要时间超时检查
                if (timeoutSecond > 0) {
                    checkTimeOut();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void addServerSocket(ServerSocketService socketService) {
        socketManagerSet.add(socketService);
    }

    public void removeServerSocket(ServerSocketService socketService) {
        socketManagerSet.remove(socketService);
    }

    public Set<ServerSocketService> getSocketManagerSet() {
        return socketManagerSet;
    }

    /**
     * 有无超时
     */
    private void checkTimeOut() {
        Runnable runnable = () -> {
            while (true) {
                try {
                    Set<ServerSocketService> tmp = new HashSet<>(socketManagerSet);
                    boolean hasRemove = false;
                    for (Iterator<ServerSocketService> iterator = tmp.iterator(); iterator.hasNext(); ) {
                        ServerSocketService serverSocketService = iterator.next();

                        // 超时未发消息
                        if (serverSocketService.getLastSendTime() + timeoutSecond * 1000 < System.currentTimeMillis()) {
                            try {
                                serverSocketService.sendMessage(new LogoutMessage());
                                serverSocketService.socket.close();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                            //线程中断
                            serverSocketService.interrupt();
                            iterator.remove();
                            hasRemove = true;
                        }
                    }

                    if (hasRemove) {
                        socketManagerSet = tmp;
                    }

                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        new Thread(runnable).start();
    }

}
